package bhwz.seac3.ui.console;

import java.util.*;
import java.util.stream.Collectors;
import java.io.*;

import test.data.*;
import bhwz.seac3.LocalBLServiceManager;
import bhwz.seac3.RMIClientBLServiceManager;
import bhwz.seac3.RMIServerBLServiceManager;
import bhwz.seac3.blservice.import_.ErrorLogPrinter;
import bhwz.seac3.blservice.query.*;
import bhwz.seac3.util.RecursiveCommandExecuter;
import bhwz.seac3.vo.*;

public class Console {

	ErrorLogPrinter elp = System.err::println;
	java.io.PrintStream out;

	HotspotQueryBLService hqbl = null;
	MatchQueryBLService mqbl = null;
	PlayerQueryBLService pqbl = null;
	TeamQueryBLService tqbl = null;

	public void setErrorLogPrinter(ErrorLogPrinter elp) {
		this.elp = elp;
	}

	public static void main(String[] args) {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		Console c = new Console();
		while (true) {
			try {
				String line = br.readLine();
				if (line.equals("exit"))
					break;
				c.execute(System.out, line.split(" "));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	public void execute(java.io.PrintStream out, String[] args) {
		try {
			if (out == null || args == null)
				return;
			this.out = out;
			startServer();
			startClient();
			initData(Arrays.asList(args));
			cmd.execute(new Command(Arrays.asList(args)));
		} catch (Exception e) {
			elp.print(e.getMessage());
		}
	}

	boolean dataInited = false;
	final String initDataCommand = "--datasource";

	void initData(List<String> cmd) {
		if (!dataInited && cmd.get(0).equals(initDataCommand)) {
			String dataPath = cmd.get(1);
			LocalBLServiceManager.getImportBLService()._import(dataPath, elp);
		}
	}

	private boolean serverStarted = false;

	void startServer() {
		if (!serverStarted) {
			try {
				RMIServerBLServiceManager.initServer();
				serverStarted = true;
			} catch (Exception e) {
				e.printStackTrace();
				out.println("服务器无法启动\n" + e.getMessage());
			}
		}
	}

	private boolean clientStarted = false;

	void startClient() {
		if (!clientStarted) {
			try {
				RMIClientBLServiceManager.initClient("localhost");
				hqbl = RMIClientBLServiceManager
						.getBLService(HotspotQueryBLService.class);
				mqbl = RMIClientBLServiceManager
						.getBLService(MatchQueryBLService.class);
				pqbl = RMIClientBLServiceManager
						.getBLService(PlayerQueryBLService.class);
				tqbl = RMIClientBLServiceManager
						.getBLService(TeamQueryBLService.class);
				clientStarted = true;
			} catch (Exception e) {
				e.printStackTrace();
				out.println("客户端无法启动\n" + e.getMessage());
			}
		}
	}

	static enum PlayerHotKingColumn {
		score, rebound, assist
	};

	private final String season = "13-14";
	private final RecursiveCommandExecuter<Command> cmd = new RecursiveCommandExecuter<Command>() {
		{
			/*-player*/
			this.addSubExecuter(new RecursiveCommandExecuter<Command>() {
				{
					this.setFormateChecker(c -> c.hasKey("-player"));
					/*-high*/
					this.addSubExecuter(new RecursiveCommandExecuter<Command>() {
						{
							this.setFormateChecker(c -> c.hasKey("-high"));
							this.addExecuteWay(c -> {
								List<PlayerVo> pvl = pqbl.query赛季总数据(season);
								List<PlayerHighInfo> phil = toPlayerHighInfoList(pvl);
								phil = sort(phil, c, playerHighInfoSorter,
										"realShot.desc");
								output(phil, c);
							});
						}
					});
					/*-total*/
					this.addSubExecuter(new RecursiveCommandExecuter<Command>() {
						{
							this.setFormateChecker(c -> c.hasKey("-total"));
							this.addExecuteWay(c -> {
								List<PlayerVo> pvl = pqbl.query赛季总数据(season);
								pvl = filte(pvl, c, playerFilter);
								List<PlayerNormalInfo> pnil = toPlayerNormalInfoList(pvl);
								pnil = sort(pnil, c, playerNormalInfoSorter,
										"point.desc");
								output(pnil, c);
							});
						}
					});
					/*-avg*/
					this.addSubExecuter(new RecursiveCommandExecuter<Command>() {
						{
							this.setFormateChecker(c -> !c.hasKey("-high")
									&& !c.hasKey("-total"));
							/*-all*/
							this.addSubExecuter(new RecursiveCommandExecuter<Command>() {
								{
									this.setFormateChecker(c -> !c
											.hasKey("-hot")
											&& !c.hasKey("-king"));
									this.addExecuteWay(c -> {
										List<PlayerVo> pvl = pqbl
												.query场均数据(season);
										pvl = filte(pvl, c, playerFilter);
										List<PlayerNormalInfo> pnil = toPlayerNormalInfoList(pvl);
										pnil = sort(pnil, c,
												playerNormalInfoSorter,
												"point.desc");
										output(pnil, c);
									});
								}
							});
							/*-hot*/
							this.addSubExecuter(new RecursiveCommandExecuter<Command>() {
								{
									this.setFormateChecker(c -> c
											.hasKey("-hot"));
									this.addExecuteWay(c -> {
										List<PlayerVo> pvl;
										PlayerHotKingColumn hotColumn;
										switch (c.getValue("-hot")) {
										case "score":
											// 得分
											pvl = hqbl
													.QueryPlayersRankedBy条件("场均得分进步");
											hotColumn = PlayerHotKingColumn.score;
											break;
										case "rebound":
											pvl = hqbl
													.QueryPlayersRankedBy条件("场均篮板进步");
											hotColumn = PlayerHotKingColumn.rebound;
											// 篮板
											break;
										case "assist":
											pvl = hqbl
													.QueryPlayersRankedBy条件("场均助攻进步");
											hotColumn = PlayerHotKingColumn.assist;
											// 助攻
											break;
										default:
											return;
										}
										List<PlayerHotInfo> phil = toPlayerHotInfoList(
												pvl, hotColumn);
										output(phil, c);
									});
								}
							});
							/*-king*/
							this.addSubExecuter(new RecursiveCommandExecuter<Command>() {
								{
									this.setFormateChecker(c -> c
											.hasKey("-king"));
									/*-daily*/
									this.addSubExecuter(new RecursiveCommandExecuter<Command>() {
										{
											this.setFormateChecker(c -> c
													.hasKey("-daily"));
											this.addExecuteWay(c -> {
												List<PlayerVo> pvl;
												PlayerHotKingColumn kingColumn;
												switch (c.getValue("-king")) {
												case "score":
													// 得分
													pvl = hqbl
															.QueryPlayersRankedBy条件("得分");
													kingColumn = PlayerHotKingColumn.score;
													break;
												case "rebound":
													pvl = hqbl
															.QueryPlayersRankedBy条件("篮板");
													kingColumn = PlayerHotKingColumn.rebound;
													// 篮板
													break;
												case "assist":
													pvl = hqbl
															.QueryPlayersRankedBy条件("助攻");
													kingColumn = PlayerHotKingColumn.assist;
													// 助攻
													break;
												default:
													return;
												}
												List<PlayerKingInfo> pkil = toPlayerKingInfoList(
														pvl, kingColumn);
												output(pkil);
											});
										}
									});
									/*-season*/
									this.addSubExecuter(new RecursiveCommandExecuter<Command>() {
										{
											this.setFormateChecker(c -> c
													.hasKey("-season"));
											this.addExecuteWay(c -> {
												List<PlayerVo> pvl;
												PlayerHotKingColumn kingColumn;
												switch (c.getValue("-king")) {
												case "score":
													// 得分
													pvl = hqbl
															.QueryPlayersRankedBy条件("场均得分");
													kingColumn = PlayerHotKingColumn.score;
													break;
												case "rebound":
													pvl = hqbl
															.QueryPlayersRankedBy条件("场均篮板");
													kingColumn = PlayerHotKingColumn.rebound;
													// 篮板
													break;
												case "assist":
													pvl = hqbl
															.QueryPlayersRankedBy条件("场均助攻");
													kingColumn = PlayerHotKingColumn.assist;
													// 助攻
													break;
												default:
													return;
												}
												List<PlayerKingInfo> pki = toPlayerKingInfoList(
														pvl, kingColumn);
												output(pki);
											});
										}
									});

								}
							});
						}
					});
				}
			});
			/*-team*/
			this.addSubExecuter(new RecursiveCommandExecuter<Command>() {
				{
					this.setFormateChecker(c -> c.hasKey("-team"));
					/*-high*/
					this.addSubExecuter(new RecursiveCommandExecuter<Command>() {
						{
							this.setFormateChecker(c -> c.hasKey("-high"));
							this.addExecuteWay(c -> {
								List<TeamVo> vol = tqbl.query赛季总数据(season);
								List<TeamHighInfo> thil = toTeamHighInfoList(vol);
								thil = sort(thil, c, teamHighInfoSorter,
										"winRate.desc");
								output(thil);
							});
						}
					});
					/*-total*/
					this.addSubExecuter(new RecursiveCommandExecuter<Command>() {
						{
							this.setFormateChecker(c -> c.hasKey("-total"));
							this.addExecuteWay(c -> {
								List<TeamVo> vol = tqbl.query赛季总数据(season);
								List<TeamNormalInfo> tnil = toTeamNormalInfoList(vol);
								tnil = sort(tnil, c, teamNormalInfoSorter,
										"point.desc");
								output(tnil);
							});
						}
					});
					/*-avg*/
					this.addSubExecuter(new RecursiveCommandExecuter<Command>() {
						{
							this.setFormateChecker(c -> !c.hasKey("-high")
									&& !c.hasKey("-total"));
							/*-all*/
							this.addSubExecuter(new RecursiveCommandExecuter<Command>() {
								{
									this.setFormateChecker(c -> !c
											.hasKey("-hot"));
									this.addExecuteWay(c -> {
										List<TeamVo> vol = tqbl
												.query场均数据(season);
										List<TeamNormalInfo> tnil = toTeamNormalInfoList(vol);
										tnil = sort(tnil, c,
												teamNormalInfoSorter,
												"point.desc");
										output(tnil);
									});
								}
							});
							/*-hot*/
							this.addSubExecuter(new RecursiveCommandExecuter<Command>() {
								{
									this.setFormateChecker(c -> c
											.hasKey("-hot"));
									this.addExecuteWay(c -> {
										List<TeamVo> vol = null;
										switch (c.getValue("-hot")) {
										case "score":
											vol=hqbl.QueryTeamsRankedBy条件("场均得分");
											// 得分
											break;
										case "rebound":
											vol=hqbl.QueryTeamsRankedBy条件("场均篮板");
											// 篮板
											break;
										case "assist":
											vol=hqbl.QueryTeamsRankedBy条件("场均助攻");
											// 助攻
											break;
										case "blockShot":
											vol=hqbl.QueryTeamsRankedBy条件("场均盖帽");
											// 盖帽
											break;
										case "steal":
											vol=hqbl.QueryTeamsRankedBy条件("场均抢断");
											// 抢断
											break;
										case "foul":
											vol=hqbl.QueryTeamsRankedBy条件("犯规");
											// 犯规
											break;
										case "fault":
											vol=hqbl.QueryTeamsRankedBy条件("失误");
											// 失误
											break;
										case "shot":
											vol=hqbl.QueryTeamsRankedBy条件("投篮命中率");
											// 投篮命中率
											break;
										case "three":
											vol=hqbl.QueryTeamsRankedBy条件("三分命中率");
											// 三分命中率
											break;
										case "penalty":
											vol=hqbl.QueryTeamsRankedBy条件("罚球命中率");
											// 罚球命中率
											break;
										case "defendRebound":
											vol=hqbl.QueryTeamsRankedBy条件("防守篮板数");
											// 防守篮板数
											break;
										case "offendRebound":
											vol=hqbl.QueryTeamsRankedBy条件("进攻篮板数");
											// 进攻篮板数
											break;
										default:
											return;
										}
										List<TeamHotInfo> thil = toTeamHotInfoList(
												vol, c.getValue("-hot"));
										output(thil);
									});
								}
							});
						}
					});
				}
			});
		}

	};

	private double getPlayerNormalInfoAttribute(PlayerNormalInfo obj,
			String name) {
		switch (name) {
		case "point":
			return obj.getPoint();
		case "rebound":
			return obj.getRebound();
		case "assist":
			return obj.getAssist();
		case "blockShot":
			return obj.getBlockShot();
		case "steal":
			return obj.getSteal();
		case "foul":
			return obj.getFoul();
		case "fault":
			return obj.getFault();
		case "minute":
			return obj.getMinute();
		case "efficient":
			return obj.getEfficiency();
		case "shot":
			return obj.getShot();
		case "three":
			return obj.getThree();
		case "penalty":
			return obj.getPenalty();
		case "doubleTwo":
			return obj.getPoint();
		default:
			return 0.0;
		}
	}

	private double getPlayerHighInfoAttribute(PlayerHighInfo obj, String name) {
		switch (name) {
		case "realShot":
			return obj.getRealShot();
		case "GmSc":
			return obj.getGmSc();
		case "shotEfficient":
			return obj.getShotEfficient();
		case "reboundEfficient":
			return obj.getReboundEfficient();
		case "offendReboundEfficient":
			return obj.getOffendReboundEfficient();
		case "defendReboundEfficient":
			return obj.getDefendReboundEfficient();
		case "assistEfficient":
			return obj.getAssistEfficient();
		case "stealEfficient":
			return obj.getStealEfficient();
		case "blockShotEfficient":
			return obj.getBlockShotEfficient();
		case "faultEfficient":
			return obj.getFaultEfficient();
		case "frequency":
			return obj.getFrequency();
		default:
			return 0.0;
		}
	}

	private double getTeamNormalInfoAttribute(TeamNormalInfo obj, String name) {
		switch (name) {
		case "point":
			return obj.getPoint();
		case "rebound":
			return obj.getRebound();
		case "assist":
			return obj.getAssist();
		case "blockShot":
			return obj.getBlockShot();
		case "steal":
			return obj.getSteal();
		case "foul":
			return obj.getFoul();
		case "fault":
			return obj.getFault();
		case "shot":
			return obj.getShot();
		case "three":
			return obj.getThree();
		case "penalty":
			return obj.getPenalty();
		case "defendRebound":
			return obj.getDefendRebound();
		case "offendRebound":
			return obj.getOffendRebound();
		default:
			return 0.0;
		}
	}

	private double getTeamHighInfoAttribute(TeamHighInfo obj, String name) {
		switch (name) {
		case "winRate":
			return obj.getWinRate();
		case "offendRound":
			return obj.getOffendRound();
		case "offendEfficient":
			return obj.getOffendEfficient();
		case "defendEfficient":
			return obj.getDefendEfficient();
		case "offendReboundEfficient":
			return obj.getOffendReboundEfficient();
		case "defendReboundEfficient":
			return obj.getDefendReboundEfficient();
		case "assistEfficient":
			return obj.getAssistEfficient();
		case "stealEfficient":
			return obj.getStealEfficient();
		default:
			return 0.0;
		}
	}

	private <T> List<T> cutPlayerNumber(List<T> l, Command c) {
		return cutNumber(l, c, 50);
	}

	private <T> List<T> cutTeamNumber(List<T> l, Command c) {
		return cutNumber(l, c, 30);
	}

	// 存疑
	private <T> List<T> cutNumber(List<T> l, Command c, int toN) {
		if (c.hasKey("-n")) {
			try {
				toN = Integer.parseInt(c.getValue("-n"));
			} catch (Exception e) {
				elp.print(e.getMessage());
			}
			if (toN < l.size())
				return l.subList(0, toN);
			else
				return l;
		} else
			return l;
	}

	private <T> void output(List<T> l, Command c) {
		if (l.size() == 0)
			return;
		if (l.get(0) instanceof PlayerNormalInfo
				|| l.get(0) instanceof PlayerHighInfo
				|| l.get(0) instanceof PlayerHotInfo) {
			l = cutPlayerNumber(l, c);
		} else if (l.get(0) instanceof TeamNormalInfo
				|| l.get(0) instanceof TeamHighInfo
				|| l.get(0) instanceof TeamHotInfo) {
			l = cutTeamNumber(l, c);
		}
		for (int i = 0; i < l.size(); i++) {
			out.println(l.get(i));
		}
	}

	private void output(Object o) {
		out.println(o);
	}

	private List<PlayerHighInfo> toPlayerHighInfoList(List<PlayerVo> vol) {
		List<PlayerHighInfo> result = new ArrayList<>();
		vol.forEach(vo -> {
			result.add(toPlayerHighInfo(vo));
		});
		return result;
	}

	private PlayerHighInfo toPlayerHighInfo(PlayerVo vo) {
		PlayerHighInfo result = null;
		try {
			TeamVo tvo = tqbl.query赛季总数据ByName(vo.get所属球队(), season);
			result = new PlayerHighInfo();
			result.setAssistEfficient(vo.get助攻率());
			result.setBlockShotEfficient(vo.get盖帽率());
			result.setDefendReboundEfficient(vo.get防守篮板率());
			result.setFaultEfficient(vo.get失误率());
			result.setFrequency(vo.get使用率());
			result.setGmSc(vo.getGmSc效率值());
			result.setLeague(tvo.get赛区());
			result.setName(vo.getName());
			result.setOffendReboundEfficient(vo.get进攻篮板率());
			result.setPosition(vo.getPosition());
			result.setRealShot(vo.get真实投篮命中率());
			result.setReboundEfficient(vo.get篮板率());
			result.setShotEfficient(vo.get投篮效率());
			result.setStealEfficient(vo.get抢断率());
			result.setTeamName(vo.getName());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	private List<PlayerHotInfo> toPlayerHotInfoList(List<PlayerVo> vol,
			PlayerHotKingColumn hotColumn) {
		List<PlayerHotInfo> result = new ArrayList<>();
		vol.forEach(vo -> {
			result.add(toPlayerHotInfo(vo, hotColumn));
		});
		return result;
	}

	private PlayerHotInfo toPlayerHotInfo(PlayerVo vo,
			PlayerHotKingColumn hotColumn) {
		PlayerHotInfo result = null;
		try {
			TeamVo tvo = tqbl.query赛季总数据ByName(vo.get所属球队(), season);
			result = new PlayerHotInfo();
			result.setField(hotColumn.name());
			result.setName(vo.getName());
			result.setPosition(vo.getPosition());
			result.setTeamName(tvo.get球队全名());
			switch (hotColumn) {
			case score:
				result.setUpgradeRate(vo.get得分近五场提升率());
				break;
			case assist:
				result.setUpgradeRate(vo.get助攻近五场提升率());
				break;
			case rebound:
				result.setUpgradeRate(vo.get篮板近五场提升率());
				break;
			}
			result.setValue(vo.get比赛信息());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	private List<PlayerNormalInfo> toPlayerNormalInfoList(List<PlayerVo> vol) {
		List<PlayerNormalInfo> result = new ArrayList<>();
		vol.forEach(vo -> {
			result.add(toPlayerNormalInfo(vo));
		});
		return result;
	}

	private PlayerNormalInfo toPlayerNormalInfo(PlayerVo vo) {
		PlayerNormalInfo result = new PlayerNormalInfo();
		result.setAge(vo.getAge());
		result.setAssist(vo.get助攻数());
		result.setBlockShot(vo.get盖帽数());
		result.setDefend(vo.get后场篮板数());
		result.setEfficiency(vo.get效率());
		result.setFault(vo.get失误数());
		result.setFoul(vo.get犯规数());
		result.setMinute(vo.get在场时间() / 60);
		result.setName(vo.getName());
		result.setNumOfGame(vo.get比赛场数());
		result.setOffend(vo.get前场篮板数());
		result.setPenalty(vo.get投篮命中率());
		result.setPoint(vo.get比赛得分());
		result.setRebound(vo.get篮板数());
		result.setShot(vo.get投篮命中率());
		result.setStart(vo.get先发场数());
		result.setSteal(vo.get投篮数());
		result.setTeamName(vo.get所属球队());
		result.setThree(vo.get三分命中率());
		return result;
	}
	
	private List<PlayerKingInfo> toPlayerKingInfoList(List<PlayerVo> vol,PlayerHotKingColumn kingColumn) {
		List<PlayerKingInfo> result = new ArrayList<>();
		vol.forEach(vo -> {
			result.add(toPlayerKingInfo(vo,kingColumn));
		});
		return result;
	}

	private PlayerKingInfo toPlayerKingInfo(PlayerVo vo,
			PlayerHotKingColumn kingColumn) {
		PlayerKingInfo result = new PlayerKingInfo();
		result.setField(kingColumn.name());
		result.setName(vo.getName());
		result.setPosition(vo.getPosition());
		result.setTeamName(vo.get所属球队());
		result.setValue(vo.get比赛信息());
		return result;
	}

	private List<TeamHighInfo> toTeamHighInfoList(List<TeamVo> vol) {
		List<TeamHighInfo> result = new ArrayList<>();
		vol.forEach(vo -> {
			result.add(toTeamHighInfo(vo));
		});
		return result;
	}

	private TeamHighInfo toTeamHighInfo(TeamVo vo) {
		TeamHighInfo result = new TeamHighInfo();
		result.setAssistEfficient(vo.get助攻率());
		result.setDefendEfficient(vo.get防守效率());
		result.setDefendReboundEfficient(vo.get防守篮板效率());
		result.setOffendEfficient(vo.get进攻效率());
		result.setOffendReboundEfficient(vo.get进攻篮板效率());
		result.setOffendRound(vo.get进攻回合());
		result.setStealEfficient(vo.get抢断效率());
		result.setTeamName(vo.get球队简称());
		result.setWinRate(vo.get胜率());
		return result;
	}

	private List<TeamHotInfo> toTeamHotInfoList(List<TeamVo> vol,
			String hotColumnName) {
		List<TeamHotInfo> result = new ArrayList<>();
		vol.forEach(vo -> {
			result.add(toTeamHotInfo(vo, hotColumnName));
		});
		return result;
	}

	private TeamHotInfo toTeamHotInfo(TeamVo vo, String hotColumnName) {
		TeamHotInfo result = new TeamHotInfo();
		result.setField(hotColumnName);
		result.setLeague(vo.get分区());
		result.setTeamName(vo.get球队简称());
		result.setValue(vo.get比赛信息());
		return result;
	}

	private List<TeamNormalInfo> toTeamNormalInfoList(List<TeamVo> vol) {
		List<TeamNormalInfo> result = new ArrayList<>();
		vol.forEach(vo -> {
			result.add(toTeamNormalInfo(vo));
		});
		return result;
	}

	private TeamNormalInfo toTeamNormalInfo(TeamVo vo) {
		TeamNormalInfo result = new TeamNormalInfo();
		result.setAssist(vo.get助攻数());
		result.setBlockShot(vo.get盖帽数());
		result.setDefendRebound(vo.get后场篮板数());
		result.setFault(vo.get失误数());
		result.setFoul(vo.get犯规数());
		result.setNumOfGame(vo.get比赛场数());
		result.setOffendRebound(vo.get前场篮板数());
		result.setPenalty(vo.get罚球命中率());
		result.setPoint(vo.get比赛得分());
		result.setRebound(vo.get篮板数());
		result.setShot(vo.get命中率());
		result.setSteal(vo.get断球数());
		result.setTeamName(vo.get球队全名());
		result.setThree(vo.get三分命中率());
		return result;
	}

	private <T> List<T> sort(List<T> l, Command c, SortMethod<T> method,
			String defaultSortCommand) {
		String sortCommand;
		if (c.hasKey("-sort")) {
			sortCommand = c.getValue("-sort");
		} else {
			sortCommand = defaultSortCommand;
		}

		String[] sortItems = sortCommand.split(",");
		String[] columns = new String[sortItems.length];
		SortMethod.SortType[] types = new SortMethod.SortType[sortItems.length];
		for (int i = 0; i < sortItems.length; i++) {
			String[] item = sortItems[i].split("\\.");
			columns[i] = item[0];
			if (item.length == 2) {
				if (item[1].equals("esc"))
					types[i] = SortMethod.SortType.ESC;
				else
					types[i] = SortMethod.SortType.DESC;
			} else {
				types[i] = SortMethod.SortType.DESC;
			}
		}
		return method.sort(l, Arrays.asList(columns), Arrays.asList(types));
	}

	static interface SortMethod<T> {
		static enum SortType {
			ESC, DESC
		};

		default List<T> sort(List<T> l, List<String> columns,
				List<SortType> types) {
			for (int i = 0; i < columns.size(); i++) {
				String column = columns.get(i);
				switch (types.get(i)) {
				case DESC:
					l.sort(new Comparator<T>() {

						@Override
						public int compare(T o1, T o2) {
							double result = compareColumnValue(o1, o2, column);
							if (result < 0)
								return 1;
							else if (result > 0)
								return -1;
							else
								return 0;
						}
					});
					break;
				case ESC:
					l.sort(new Comparator<T>() {

						@Override
						public int compare(T o1, T o2) {
							double result = compareColumnValue(o1, o2, column);
							if (result < 0)
								return -1;
							else if (result > 0)
								return 1;
							else
								return 0;
						}
					});
					break;
				}
			}
			return l;
		}

		double compareColumnValue(T o1, T o2, String column);
	}

	private final SortMethod<PlayerHighInfo> playerHighInfoSorter = (o1, o2,
			column) -> {
		return getPlayerHighInfoAttribute(o1, column)
				- getPlayerHighInfoAttribute(o2, column);
	};
	private final SortMethod<PlayerNormalInfo> playerNormalInfoSorter = (o1,
			o2, column) -> {
		return getPlayerNormalInfoAttribute(o1, column)
				- getPlayerNormalInfoAttribute(o2, column);
	};
	private final SortMethod<TeamHighInfo> teamHighInfoSorter = (o1, o2, column) -> {
		return getTeamHighInfoAttribute(o1, column)
				- getTeamHighInfoAttribute(o2, column);
	};
	private final SortMethod<TeamNormalInfo> teamNormalInfoSorter = (o1, o2,
			column) -> {
		return getTeamNormalInfoAttribute(o1, column)
				- getTeamNormalInfoAttribute(o2, column);
	};

	static interface FilteMethod<T> {
		List<T> filte(List<T> list, List<String> columns, List<String> values);
	}

	private <T> List<T> filte(List<T> l, Command c, FilteMethod<T> filter) {
		if (c.hasKey("-filter")) {
			String filterValue = c.getValue("-filter");
			String[] groups = filterValue.split(",");
			List<String> keys = new ArrayList<>();
			List<String> values = new ArrayList<>();
			for (int i = 0; i < groups.length; i++) {
				String[] key_value = groups[i].split("\\.");
				if (key_value.length == 2) {
					keys.add(key_value[0]);
					values.add(key_value[1]);
				}
			}
			return filter.filte(l, keys, values);
		} else {
			return l;
		}
	}

	private final FilteMethod<PlayerVo> playerFilter = (l, columns, values) -> {
		int index;
		index = columns.indexOf("position");
		if (index != -1) {
			switch (values.get(index)) {
			case "F":
				l = l.stream()
						.filter(e -> e.getPosition().toUpperCase()
								.contains("F")).collect(Collectors.toList());
				break;
			case "G":
				l = l.stream()
						.filter(e -> e.getPosition().toUpperCase()
								.contains("G")).collect(Collectors.toList());
				break;
			case "C":
				l = l.stream()
						.filter(e -> e.getPosition().toUpperCase()
								.contains("C")).collect(Collectors.toList());
				break;
			}
		}
		index = columns.indexOf("league");
		if (index != -1) {
			switch (values.get(index)) {
			case "West":
				l = l.stream()
						.filter(e -> e.get所属联盟().equals("Pacific")
								|| e.get所属联盟().equals("Northwest")
								|| e.get所属联盟().equals("Southwest"))
						.collect(Collectors.toList());
				break;
			case "East":
				l = l.stream()
						.filter(e -> e.get所属联盟().equals("Southeast")
								|| e.get所属联盟().equals("Central")
								|| e.get所属联盟().equals("Atlantic"))
						.collect(Collectors.toList());
				break;
			}
		}
		index = columns.indexOf("age");
		if (index != -1) {
			switch (values.get(index)) {
			case "<=22":
				l = l.stream().filter(e -> e.getAge() <= 22)
						.collect(Collectors.toList());
				break;
			case "22<X<=25":
				l = l.stream().filter(e -> e.getAge() > 22 && e.getAge() <= 25)
						.collect(Collectors.toList());
				break;
			case "25<X<=30":
				l = l.stream().filter(e -> e.getAge() > 25 && e.getAge() <= 30)
						.collect(Collectors.toList());
				break;
			case ">30":
				l = l.stream().filter(e -> e.getAge() > 30)
						.collect(Collectors.toList());
				break;
			}
		}
		return l;
	};

}
